package formatter

import (
	"encoding/json"
	"fmt"
	"strings"
	"sync"

	"gitee.com/simonxie979/skymeta/logutil/port"

	"github.com/sirupsen/logrus"
)

var logDataPool = &sync.Pool{
	New: func() any {
		return &LogData{}
	},
}

type LogData struct {
	Time    string `json:"Time,omitempty"`
	Level   string `json:"Level,omitempty"`
	Message string `json:"Message,omitempty"`
	Tag     string `json:"Tag,omitempty"`
	Caller  string `json:"Caller,omitempty"`
	Stack   string `json:"Stack,omitempty"`
}

func (obj *LogData) Init(entry *logrus.Entry) {
	obj.Time = entry.Time.Format(port.TimeFormat)
	obj.Level = entry.Level.String()
	obj.Message = entry.Message
	obj.Tag = entry.Data[port.TagKey].(string)
	obj.Caller = entry.Data[port.FuncKey].(string)
	obj.Stack = entry.Data[port.StackTraceKey].(string)
}

func (obj *LogData) Text() (data []byte, err error) {
	length := len(obj.Time) + 42 // "[%s][%5s]" + '\n' + more space
	length += len(obj.Message) + len(obj.Tag) + len(obj.Caller) + len(obj.Stack)

	data = make([]byte, 0, length)
	data = append(data, []byte("["+obj.Time+"]")...)
	data = append(data, []byte(fmt.Sprintf("[%7s] ", strings.ToUpper(obj.Level)))...)
	data = append(data, []byte(obj.Message)...)
	if obj.Tag != "" {
		data = append(data, []byte(" "+port.TagKey+"=\""+obj.Tag+"\"")...)
	}
	if obj.Caller != "" {
		data = append(data, []byte(" "+port.FuncKey+"=\""+obj.Caller+"\"")...)
	}
	if obj.Stack != "" {
		data = append(data, '\n')
		data = append(data, []byte(obj.Stack)...)
	}
	data = append(data, '\n')
	return
}

func (obj *LogData) Json() ([]byte, error) {
	return json.Marshal(obj)
}
